﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Forms;
using System.IO;

namespace Red.Controls.Utils
{
    /// <summary>
    /// Contains all of the configuration parameters for <see cref="FolderBrowserCommand"/>
    /// </summary>
    /// <example>
    /// Where "TargetProperty" is the string property that will store the selected folder
    /// <code><![CDATA[
    /// <ResourceDictionary>
    ///     <utils:FolderBrowserCommadParam x:Key="FolderBrowserCommandParam" Parent="{Binding}" Property="TargetProperty"/>
    ///     <utils:FolderBrowserCommand x:Key="FolderBrowserCommand"/>
    /// </ResourceDictionary>]]>
    /// </code>
    /// </example>
    public sealed class FolderBrowserCommandParam : Freezable
    {
        // FolderBrowserCommandParam inherits from Freezable so that we inherit the DataContext of the parent:
        // http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
        protected override Freezable CreateInstanceCore()
        {
            return new FolderBrowserCommandParam();
        }

        public static readonly DependencyProperty ParentProperty = DependencyProperty.Register( "Parent", typeof( object ), typeof( FolderBrowserCommandParam ), new FrameworkPropertyMetadata( null ) );

        public object Parent
        {
            get { return GetValue( ParentProperty ); }
            set { SetValue( ParentProperty, value ); }
        }

        public string Property { get; set; }

        public string Value
        {
            get
            {
                var property = Parent.GetType().GetProperty( Property );
                return (string)property.GetValue( Parent );
            }
            set
            {
                var property = Parent.GetType().GetProperty( Property );
                property.SetValue( Parent, value );
            }
        }
    }

    /// <summary>
    /// A Method of invoking the Folder Browser dialog.
    /// It also requires an associated <see cref="FolderBrowserCommandParam"/> instance specified as the command parameter
    /// </summary>
    /// <example>
    /// This is a continuation of the <see cref="FolderBrowserCommandParam"/> example
    /// <code>
    ///     <Button Text="Press me!" Command="{StaticResource FolderBrowserCommand}" CommandParameter="{StaticResource FolderBrowserCommandParam}" />
    /// </code>
    /// </example>
    public sealed class FolderBrowserCommand : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute( object parameter )
        {
            return true;
        }

        public void Execute( object parameter )
        {
            var param = parameter as FolderBrowserCommandParam;
            if ( param == null )
                return;

            string initialPath = null;
            if ( !String.IsNullOrWhiteSpace( param.Value ) )
            {
                DirectoryInfo directory = new DirectoryInfo( param.Value );
                initialPath = directory.FullName;
            }

            var folderBrowserDialog = new FolderBrowserDialog { SelectedPath = initialPath };
            if ( folderBrowserDialog.ShowDialog() == DialogResult.OK )
                param.Value = folderBrowserDialog.SelectedPath;
        }
    }
}
